package com.atguigu.dynamic.aspect;

import com.atguigu.dynamic.annotation.DS;
import com.atguigu.dynamic.annotation.Type;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 动态数据源切换切面，切入Service层
 *
 * @author szj
 * @since 2021-03-21 16:46
 */
@Order(-1)
@Aspect
@Component
@Slf4j
public class DataSourceAspect {

    @Pointcut("execution(* com.atguigu.dynamic.service..*.*(..))")
    public void pointcut() {
    }

    @Before(value = "pointcut()")
    public void before(JoinPoint joinPoint) {
        try {
//            获取Impl类
            Class<?> aClass = joinPoint.getTarget().getClass();
            Type dataSource = Type.USER;
//            查看Impl类上是否标注@DS注解
            if (aClass.isAnnotationPresent(DS.class)) {
//                获取注解中标注的值，该值为数据源的key
                DS ds = aClass.getAnnotation(DS.class);
                dataSource = ds.value();
                log.info("[Switch Class's Key:]" + dataSource);
            }
            Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
            if (method.isAnnotationPresent(DS.class)) {
//                获取注解中标注的值，该值为数据源的key
                DS ds = method.getAnnotation(DS.class);
                dataSource = ds.value();
                log.info("[Switch Method's Key:]" + dataSource);
            }
            log.info("[Using:]" + dataSource);
            DataSourceHolder.setKey(dataSource);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @After(value = "pointcut()")
    public void after() {
        DataSourceHolder.clear();
        log.info("[Clear Others DataSources And Use Default DataSource]");
    }
}
